import {
  regReplaceExpression,
  regReplaceBlankSpace,
  regFloatOrIntegerPrice,
  regFloat,
  regNoNegativeNumberFloat
} from './../javascript/regulars';

/**
 * 发起微信支付
 * @param {Number} timeStamp 时间戳
 * @param {String} nonceStr 随机字符串
 * @param {String} package 统一下单接口返回的 prepay_id 参数值
 * @param {String} signType 签名算法，暂支持 MD5
 * @param {String} paySign 签名  
 */
export const weixinPay = async (res) => {
  return new Promise((resolve, reject) => {
    wx.requestPayment({
      timeStamp: res.timeStamp,
      nonceStr: res.nonceStr,
      package: res.package,
      signType: res.signType,
      paySign: res.paySign,
      success: res => {
        console.log('支付成功=>', res)
        resolve(res);
        wx.showToast({
          title: '支付成功',
          icon: 'success',
          duration: 3000,
          mask: true
        })
      },
      fail: res => {
        console.warn('[支付失败]=>', res)
        if (res.errMsg === 'requestPayment:fail cancel') {
          console.warn('用户取消支付')
          reject(res);
        } else {
          wx.showToast({
            title: '支付失败',
            icon: 'none',
          })
        }
      },
      complete: () => {
        // wx.hideLoading();
      },
    })
  })
}

//小于10补零
export const offsetZero = (value) => {
  if (value < 10) return '0' + value;
  return value;
}

/**
 * 时间戳转日期
 * @param {String} types 转换类型
 * @param {String} timestamp 时间戳
 */
export const timestampToDate = (timestamp, types) => {

  // 补全为13位
  let arrTimestamp = (timestamp + '').split('');
  for (var start = 0; start < 13; start++) {
    if (!arrTimestamp[start]) {
      arrTimestamp[start] = '0';
    }
  }
  timestamp = arrTimestamp.join('') * 1;

  let date = new Date(timestamp);
  let year = date.getFullYear();
  let month = date.getMonth() + 1;
  let day = date.getDate();
  let hours = date.getHours();
  let minutes = date.getMinutes();
  let seconds = date.getSeconds();

  switch (types) {
    case 'YY-MM-DD':
      return year + '-' + offsetZero(month) + '-' + offsetZero(day);
    case 'HH:MM':
      return offsetZero(hours) + ':' + offsetZero(minutes);
    case 'HH-MM':
      return offsetZero(hours) + '-' + offsetZero(minutes);
    case 'HH:MM:SS':
      return offsetZero(hours) + ':' + offsetZero(minutes) + ':' + offsetZero(seconds);
    case 'HH:MM-HH:MM':
      return offsetZero(hours) + ':' + offsetZero(minutes) + '-' + offsetZero(hours) + ':' + offsetZero(minutes);
    case 'MM月DD日':
      return offsetZero(month) + '月' + offsetZero(day) + '日';
    case 'YY年MM月DD日':
      return year + '年' + offsetZero(month) + '月' + offsetZero(day) + '日';
      //YY-MM-DD HH:MM 
    default:
      return year + '-' + offsetZero(month) + '-' + offsetZero(day) + ' ' + offsetZero(hours) + ':' + offsetZero(minutes);
  }
}

/**
 * 时间戳转日期
 * @param {Number} timestamp 时间戳
 */
export const formatMsgTimeBlobal = (timestamp) => {
  // 补全为13位
  let arrTimestamp = (timestamp + '').split('');
  for (let i = 0; i < 13; i++) {
    if (!arrTimestamp[i]) {
      arrTimestamp[i] = '0';
    }
  }
  timestamp = arrTimestamp.join('') * 1;

  let minute = 1000 * 60;
  let hour = minute * 60;
  let day = hour * 24;
  let month = day * 30;
  let now = new Date().getTime();
  let yearN = new Date().getFullYear(); //当前年份
  let diffValue = now - timestamp;

  // 计算差异时间量级
  let monthC = diffValue / month;
  let weekC = diffValue / (7 * day);
  let dayC = diffValue / day;
  let hourC = diffValue / hour;
  let minC = diffValue / minute;
  let date = new Date(timestamp);

  let yearS = date.getFullYear();
  let monthS = date.getMonth() + 1;
  let dayS = date.getDate();
  let hoursS = date.getHours();
  let minuteS = date.getMinutes();

  const returnWeek = (dayC) => {
    //今天内
    if (dayC < 1) {
      return `${offsetZero(hoursS)}:${offsetZero(minuteS)}`;
    } else if (dayC > 1 && dayC < 2) {
      return `昨天`
    } else {
      return `${offsetZero(monthS)}.${offsetZero(dayS)}`
    }
  }

  if (parseInt(yearS) !== parseInt(yearN)) {
    // 超过1年，直接显示年月日
    return yearS + '.' + offsetZero(monthS) + '.' + offsetZero(dayS);
  } else if (monthC >= 1 || weekC >= 1) {
    return `${offsetZero(monthS)}.${offsetZero(dayS)}`;
  } else if (dayC > 0 && dayC < 7) {
    return returnWeek(dayC);
  }
  return `${offsetZero(hoursS)}:${offsetZero(minuteS)}`;

  // if (parseInt(yearS) !== parseInt(yearN)) {
  //   // 超过1年，直接显示年月日
  //   return yearS + '.' + offsetZero(monthS) + '.' + offsetZero(dayS);
  // } else if (monthC >= 1 || weekC >= 1) {
  //   return `${offsetZero(monthS)}.${offsetZero(dayS)}`;
  // } else if (dayC > 0 && dayC < 7) {
  //   return returnWeek(dayC);
  // } else if (hourC >= 1) {
  //   return `${offsetZero(hoursS)}:${offsetZero(minuteS)}`;
  // } else if (minC >= 1) {
  //   return parseInt(minC) + "分钟前";
  // }
  // return '刚刚';
}

/**
 * 时间戳转时分秒
 * @times:今天剩余多少秒
 */
export const timeStampToHMS = (times) => {
  let hours = Math.floor(times / 3600);
  let minutes = Math.floor(times % 3600 / 60);
  let seconds = Math.ceil(times % 60);
  let Times = offsetZero(hours) + ":" + offsetZero(minutes) + ":" + offsetZero(seconds);
  return Times;
}

/**
 * @获取当前时间，年月日
 * @ttype {String} 返回格式类型
 */
export const getThisTime = (ttype) => {
  let date = new Date(),
    year = date.getFullYear(),
    month = date.getMonth() + 1,
    day = date.getDate(),
    h = date.getHours(),
    m = date.getMinutes();

  switch (ttype) {
    case 'YY.MM.DD':
      return year + '.' + offsetZero(month) + '.' + offsetZero(day);
    case 'YY.MM.DD HH:MM':
      return year + '.' + offsetZero(month) + '.' + offsetZero(day) + ' ' + offsetZero(h) + ':' + offsetZero(m);
    case 'YY/MM/DD HH:MM':
      return year + '/' + offsetZero(month) + '/' + offsetZero(day) + ' ' + offsetZero(h) + ':' + offsetZero(m);
    case 'YY-MM-DD HH:MM':
      return year + '-' + offsetZero(month) + '-' + offsetZero(day) + ' ' + offsetZero(h) + ':' + offsetZero(m);
    case 'YY-MM-DD':
      return year + '-' + offsetZero(month) + '-' + offsetZero(day);
    case 'YY-MM':
      return year + '-' + offsetZero(month);
    default:
      return year + '' + offsetZero(month) + '' + offsetZero(day);
  }
}

/**
 * 对象合并
 * @param {Object} obj1 对象1
 * @param {Object} obj2 对象2
 */
export const assign = (obj1, obj2 = {}) => {
  for (var name in obj1) {
    if (typeof obj1[name] === "object") { //先判断一下obj[name]是不是一个对象
      obj2[name] = (obj1[name].constructor === Array) ? [] : {}; //我们让要复制的对象的name项=数组或者是json
      copy(obj1[name], obj2[name]); //然后来无限调用函数自己 递归思想
    } else {
      obj2[name] = obj1[name]; //如果不是对象，直接等于即可，不会发生引用。
    }
  }
  return obj2; //然后在把复制好的对象给return出去
}

/**
 * 不能输入表情
 * @param {String} value 用户输入文本
 */
export const regEmoji = (value) => {
  if (regReplaceExpression.test(value)) {
    wx.showToast({
      title: '不允许输入表情',
      icon: 'none',
    })
    value = value.replace(regReplaceExpression, '');
    value = value.replace(regReplaceBlankSpace, "");
    return value;
  } else {
    return value;
  }
}

/**
 * 10000 => "10,000"
 * @param {number} num
 */
export const toThousandFilter = (num) => {
  return (+num || 0).toString().replace(/^-?\d+/g, m => m.replace(/(?=(?!\b)(\d{3})+$)/g, ','))
}

/**
 * 判断数字是不是正浮点数
 */
export const checkAfterTwo = (num) => {
  let zhengFloat = /^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$/;
  if (zhengFloat.test(num)) {
    if (Number(num) != NaN) {
      return true;
    }
  }
  if (num == 0) {
    return true;
  }
  return false;
}

/**
 *  过滤浮点数后面只有两位小数
 */
export const getFloatNumberLaterTwoDigit = (num) => {
  let point_reg = /^./;
  let arr = [],
    arr2 = [],
    str1 = '',
    str2 = '';
  num = String(num);
  if (num == '0') {
    return num
  }
  if (point_reg.test(num)) {
    arr = num.split('.');
    if (arr.length > 1 && arr[1].length > 1) {
      arr2 = arr[1].split('');
      str1 = String(arr2[0]) + String(arr2[1]);
      str2 = String(arr[0]) + '.' + str1;
      return str2;
    }
    return num;
  }
  return num;
}

/**
 *  过滤浮点数后面只有两位小数
 */
export const getFloatNumberLaterTwoDigits = (num) => {
  let point_reg = /^./;
  let arr = [],
    arr2 = [],
    str1 = "",
    str2 = "";
  num = String(num);
  if (num == "0") return num;
  if (point_reg.test(num)) {
    arr = num.split(".");
    if (arr.length > 1 && arr[1].length > 1) {
      arr2 = arr[1].split("");
      //小数位至少2个
      let t2 = 0;
      if (arr2.length > 2) {
        let t3 = parseInt(arr2[2]); //如果第三位大于5，向前进1
        t2 = t3 > 5 ? parseInt(arr2[1]) + 1 : parseInt(arr2[1]);
      }

      if (parseInt(arr2[0]) > 0 || parseInt(arr2[1]) > 0) {
        str1 = String(arr2[0]) + String(arr2[1]);
        str2 = String(arr[0]) + "." + str1;
      } else {
        if (parseInt(arr2[0]) <= 0 && parseInt(arr2[1]) <= 0) {
          str2 = String(arr[0]);
        }
      }
      return str2;
    }
    return num;
  }
  return num;
}

/**
 * 按照减号分割金额，返回不带减号的金额
 */
export const accordanceReductionSplitPrice = (price) => {
  let _price = price.toString().split("-");
  return _price[1];
}

/**
 * 过滤金额（浮点数或整数），将小数点后两位为零的过滤为正整数，如果不为零则保留
 */
export const filterPrice = (price) => {
  if (regFloatOrIntegerPrice.test(price)) {
    //浮点数
    if (regFloat.test(price)) {
      // console.log('浮点数', price);
      price = parseFloat(price);
      return parseFloat(price.toFixed(2));
    }
    // 非零开头的正整数
    if (regNoNegativeNumberFloat.test(price)) {
      // console.log('非零开头的正整数=>',price);
      price = parseFloat(price);
      return price;
    }
    throw `${price} 金额格式错误`;
  } else {
    throw `${price} price应该是一个浮点数或整数`;
  }
}


/**
 * @授权
 * 保存图片到相册授权
 * @scope {String} 授权项
 */
export const authorizeCheck = (scope) => {
  return new Promise((resolve, reject) => {
    wx.authorize({
      scope: "scope." + scope,
      success: () => {
        resolve(true);
      },
      fail: res => {
        console.log('[authorize fail]', res)
        wx.hideLoading();
        resolve(false);
      },
    })
  })
}

/**
 * 保存图片到用户本地
 * @path {String} 保存资源临时路径
 */
export const saveImageToPhotosAlbum = (path) => {
  return new Promise((resolve, reject) => {
    wx.saveImageToPhotosAlbum({
      filePath: path,
      success: res => {
        wx.showModal({
          title: "保存成功",
          content: '整为名片已保存至手机相册',
          showCancel: false,
          confirmText: '知道了',
        })
        resolve(res);
      },
      fail: res => {
        console.log('res', res)
        wx.hideLoading();
        if (res.errMsg != 'saveImageToPhotosAlbum:fail cancel') {
          wx.showToast({
            title: '保存图片失败',
            icon: 'none',
          })
        }
        reject(res);
      }
    })
  })
}

//节流函数
export const throttle = (func, interval = 500) => {
  let timeout;
  let startTime = new Date();
  return function (event) {
    clearTimeout(timeout);
    let curTime = new Date();
    if (curTime - startTime <= interval) {
      //小于规定时间间隔时，用setTimeout在指定时间后再执行
      timeout = setTimeout(() => {
        func.call(this, event);
      }, interval)
    } else {
      //重新计时并执行函数
      startTime = curTime;
      func.call(this, event);
    }
  }
}

/**
 * 微信客户端和小程序基础库版本号比较
 * @param {String} v1 版本号1
 * @param {String} v2 版本号2
 */
export const compareVersion = (v1, v2) => {
  v1 = v1.split('.')
  v2 = v2.split('.')
  const len = Math.max(v1.length, v2.length)

  while (v1.length < len) {
    v1.push('0')
  }
  while (v2.length < len) {
    v2.push('0')
  }

  for (let i = 0; i < len; i++) {
    const num1 = parseInt(v1[i])
    const num2 = parseInt(v2[i])

    if (num1 > num2) {
      return true;
    } else if (num1 < num2) {
      return false;
    }
  }
  return false;
}

/**
 * 比较某个版本号是否大于当前运行系统版本
 * @param {String} vnum 版本号，10.2.6
 */
export const systemVersion = (vnum) => {
  if (isEmpty(vnum)) return false;
  let _system = (app.globalData.sysInfo.system).split(' ');
  let _compareVersion = compareVersion(_system[1], vnum)
  console.log(`[systemVersion=>]${_system[1]}>${vnum} = ${_compareVersion}`)
  return _compareVersion;
}


/**
 * 格式化证件号码，1*************32
 * @param {Number|String} idNo 
 */
export const formattedIdNo = (idNo) => {
  let snowString = '',
    _idNo = idNo.split('');
  for (let i = 0; i < _idNo.length - 3; i++) {
    snowString += '*';
  }

  return idNo.replace(idNo.substring(1, idNo.length - 2), snowString);
}

/**
 * 判断是否是基本数据类型
 * @param value 
 */
function isPrimitive(value) {
  return (typeof value === 'string' ||
    typeof value === 'number' ||
    typeof value === 'symbol' ||
    typeof value === 'boolean')
}

/**
 * 判断是否是一个js对象
 * @param value 
 */
function isObject(value) {
  return Object.prototype.toString.call(value) === "[object Object]"
}

/**
 * 深拷贝一个值【数组、对象深拷贝】
 * @param value 
 */
export function cloneDeep(value) {
  // 记录被拷贝的值，避免循环引用的出现
  let memo = {};

  function baseClone(value) {
    let res;
    // 如果是基本数据类型，则直接返回
    if (isPrimitive(value)) {
      return value;
      // 如果是引用数据类型，我们浅拷贝一个新值来代替原来的值
    } else if (Array.isArray(value)) {
      res = [...value];
    } else if (isObject(value)) {
      res = {
        ...value
      };
    }

    // 检测我们浅拷贝的这个对象的属性值有没有是引用数据类型。如果是，则递归拷贝
    Reflect.ownKeys(res).forEach(key => {
      if (typeof res[key] === "object" && res[key] !== null) {
        //此处我们用memo来记录已经被拷贝过的引用地址。以此来解决循环引用的问题
        if (memo[res[key]]) {
          res[key] = memo[res[key]];
        } else {
          memo[res[key]] = res[key];
          res[key] = baseClone(res[key])
        }
      }
    })
    return res;
  }

  return baseClone(value)
}

//通过js的内置对象JSON来进行数组对象的深拷贝
export function deepCloneJson(obj) {
  var _obj = JSON.stringify(obj),
    objClone = JSON.parse(_obj);
  return objClone;
}

export function getSystemInfo() {
  if (app && app.globalSystemInfo && !app.globalSystemInfo.ios) {
    return app.globalSystemInfo;
  } else {
    let systemInfo = wx.getSystemInfoSync();
    let ios = !!(systemInfo.system.toLowerCase().search('ios') + 1);
    let rect;
    try {
      rect = wx.getMenuButtonBoundingClientRect ? wx.getMenuButtonBoundingClientRect() : null;
      rect = {
        bottom: 40,
        height: 32,
        left: 254,
        right: 351,
        top: 8,
        width: 96
      }
      if (rect === null) {
        throw 'getMenuButtonBoundingClientRect error';
      }
      //取值为0的情况  有可能width不为0 top为0的情况
      if (!rect.width || !rect.top || !rect.left || !rect.height) {
        throw 'getMenuButtonBoundingClientRect error';
      }
      //部分机型（比如：Meizu Note5）获取到的胶囊按钮top小于状态栏statusBarHeight高度
      if (rect.top < systemInfo.statusBarHeight) {
        throw 'getMenuButtonBoundingClientRect error';
      }
    } catch (error) {
      let gap = ''; //胶囊按钮上下间距 使导航内容居中
      let width = 96; //胶囊的宽度
      if (systemInfo.platform === 'android') {
        gap = 8;
        width = 96;
      } else if (systemInfo.platform === 'devtools') {
        if (ios) {
          gap = 5.5; //开发工具中ios手机
        } else {
          gap = 7.5; //开发工具中android和其他手机
        }
      } else {
        gap = 4;
        width = 88;
      }
      if (!systemInfo.statusBarHeight) {
        //开启wifi的情况下修复statusBarHeight值获取不到
        systemInfo.statusBarHeight = systemInfo.screenHeight - systemInfo.windowHeight - 20;
      }
      rect = {
        //获取不到胶囊信息就自定义重置一个
        bottom: systemInfo.statusBarHeight + gap + 32,
        height: 32,
        left: systemInfo.windowWidth - width - 10,
        right: systemInfo.windowWidth - 10,
        top: systemInfo.statusBarHeight + gap,
        width: width
      };
      // console.log('error', error);
      // console.log('rect', rect);
    }

    let navBarHeight = '';
    if (!systemInfo.statusBarHeight) {
      systemInfo.statusBarHeight = systemInfo.screenHeight - systemInfo.windowHeight - 20;
      navBarHeight = (function () {
        let gap = rect.top - systemInfo.statusBarHeight;
        return 2 * gap + rect.height;
      })();

      systemInfo.statusBarHeight = 0;
      systemInfo.navBarExtendHeight = 0; //下方扩展4像素高度 防止下方边距太小
    } else {
      navBarHeight = (function () {
        let gap = rect.top - systemInfo.statusBarHeight;
        return systemInfo.statusBarHeight + 2 * gap + rect.height;
      })();
      if (ios) {
        systemInfo.navBarExtendHeight = 4; //下方扩展4像素高度 防止下方边距太小
      } else {
        systemInfo.navBarExtendHeight = 0;
      }
    }
    systemInfo.navBarHeight = navBarHeight; //导航栏高度不包括statusBarHeight
    systemInfo.capsulePosition = rect; //右上角胶囊按钮信息bottom: 58 height: 32 left: 317 right: 404 top: 26 width: 87 目前发现在大多机型都是固定值 为防止不一样所以会使用动态值来计算nav元素大小
    systemInfo.ios = ios; //是否ios
    if (app) {
      app['globalSystemInfo'] = systemInfo; //将信息保存到全局变量中,后边再用就不用重新异步获取了
    }
    return systemInfo;
  }
}


/**
 * 取URL参数
 * @param {String} url 链接
 * @param {String} variable 属性
 */
export function getQueryVariable(url, variable) {
  let query = url.split('?');
  if (query && query.length > 0) {
    let vars = query[1].split("&");
    for (let i = 0; i < vars.length; i++) {
      let pair = vars[i].split("=");
      if (pair[0] == variable) {
        return pair[1];
      }
    }
  }
  return null;
}

// 是否为空
export function isEmpty(str) {
  return (str === null || str === "" || str === undefined || JSON.stringify(str) === "{}" || str == 'undefined' || str.length == 0);
}


//文件原本后缀名
export function getFileSuffix(file) {
  if (isEmpty(file)) return file;
  let _file = file.split('.');
  return _file[_file.length - 1]
}